import logging

import multiprocessing

# from multiprocessing.pool import Pool

import numpy as np
from deap import base, creator, tools

from solution_methods.GA.src.operators import (
    evaluate_individual, evaluate_population, init_individual, init_population,
    mutate_sequence_exchange, mutate_shortest_proc_time, pox_crossover)
from solution_methods.helper_functions import set_seeds


def initialize_run(jobShopEnv, **kwargs):
    """
    初始化遗传算法运行，设置DEAP工具箱、统计信息、名人堂和初始种群。

    参数:
        jobShopEnv: 需要优化的作业车间环境。
        pool: 用于并行处理的多进程池。
        kwargs: 设置算法参数的其他关键字参数。

    返回:
        tuple: (initial_population, toolbox, stats, hof)
            - initial_population: 初始化的种群。
            - toolbox: 包含注册操作符的DEAP工具箱。
            - stats: 跟踪进化进度的统计对象。
            - hof: 用于存储最佳个体的名人堂。
    """
    # 设置随机种子
    set_seeds(kwargs["algorithm"].get("seed", None))

    # 如果尚未配置，则初始化日志记录
    if not logging.getLogger().hasHandlers():
        logging.basicConfig(level=logging.INFO)

    # 设置DEAP创建类
    if not hasattr(creator, "Fitness"):
        creator.create("Fitness", base.Fitness, weights=(-1.0,))
    if not hasattr(creator, "Individual"):
        creator.create("Individual", list, fitness=creator.Fitness)

    # 定义并在DEAP工具箱中注册操作符和函数
    toolbox = base.Toolbox()

    # 初始化多进程池
    if kwargs['algorithm']['multiprocessing']:
        pool = multiprocessing.Pool()
        toolbox.register("map", pool.map)

    # 注册个体和遗传操作符
    toolbox.register("init_individual", init_individual, creator.Individual, jobShopEnv=jobShopEnv)
    toolbox.register("mate_TwoPoint", tools.cxTwoPoint)
    toolbox.register("mate_Uniform", tools.cxUniform, indpb=0.5)
    toolbox.register("mate_POX", pox_crossover, nr_preserving_jobs=1)
    toolbox.register("mutate_machine_selection", mutate_shortest_proc_time, jobShopEnv=jobShopEnv)
    toolbox.register("mutate_operation_sequence", mutate_sequence_exchange)
    toolbox.register("select", tools.selTournament, k=kwargs['algorithm']['population_size'], tournsize=3)
    toolbox.register("evaluate_individual", evaluate_individual, jobShopEnv=jobShopEnv)

    # 设置统计信息跟踪
    stats = tools.Statistics(lambda ind: ind.fitness.values)
    stats.register("avg", np.mean, axis=0)
    stats.register("std", np.std, axis=0)
    stats.register("min", np.min, axis=0)
    stats.register("max", np.max, axis=0)

    # 创建名人堂以跟踪最佳个体
    hof = tools.HallOfFame(1)

    try:
        # 初始化种群
        initial_population = init_population(toolbox, kwargs['algorithm']['population_size'])
        # 评估初始种群的适应度
        fitnesses = evaluate_population(toolbox, initial_population)

        # 为个体分配适应度值
        for ind, fit in zip(initial_population, fitnesses):
            ind.fitness.values = fit

    except Exception as e:
        logging.error(f"在初始种群评估期间发生错误：{e}")
        return None, None, None, None

    return initial_population, toolbox, stats, hof
